Industrial controllers are special purpose computers used for controlling industrial processes or manufacturing equipment.
Under the direction of a stored program, the industrial controller examines a series of inputs reflecting the status of a controlled process and changes outputs effecting control of the process. The inputs and outputs are most simply binary, that is "on" or "off"; however, analog inputs and outputs, taking on a continuous range of values, are also used.
Industrial controllers are frequently programmed in a "relay ladder" language where instructions are represented graphically by "contacts" and "coils" of virtual relays connected and arranged in ladder-like rungs. This relay ladder language, with its input contacts and output coils, reflects the emphasis in industrial control on the processing of large amounts of input and output data. The relay ladder language also reflects the fact that most industrial control is "real-time"; that is, an ideal industrial controller behaves as if it were actually composed of multiple relays connected in parallel rungs to provide outputs in essentially instantaneous response to changing inputs.
Other industrial control languages are also used including: function block languages which represent instructions as functional blocks having inputs and outputs connected to the inputs of other functional blocks; sequential function chart languages which represent the control process as a series of discrete states responsive to historical input and output data, and structured text languages which most closely resemble conventional computer programs such as FORTRAN and C.
Unlike programs written for industrial control, conventional computer programs frequently contain instructions causing loops in their execution pending an external event, for example, where the processor repeats a test instruction until an input condition is satisfied. Such loops can cause the execution time of the program to vary substantially, depending on how soon the external condition is satisfied.
In contrast, programs written for real-time control normally are fashioned to have a well defined execution time as they cycle through the program from beginning to end. This is a result, in part, of the need for these programs to process many inputs and outputs concurrently. If the processor "waits" for one input, e.g. by looping, this waiting adversely affects the speed of the processing of the other inputs.
For a control program written in ladder form, for example, the program continuously scans the "rungs" of the ladder reading inputs and writing outputs determined from those inputs and the logic of the ladder. The scanning time is relatively constant.
It would be desirable to write large programs for industrial controllers as separate "tasks" that could be independently run and checked. For example, different machines along a single assembly line might be controlled with separate programs, each written as a separate task. The tasks for different machines, although developed separately, could then run on a single processor in a manner so as to appear to be executing simultaneously. Apparent simultaneous execution would be obtained by rapidly switching a single processor between tasks.
It is known to run multiple "periodic" tasks, i.e, tasks that must be run at a regular defined interval, on a single processor by switching between the tasks based on a schedule. The schedule is designed to accommodate the desired frequency with which the task should be run (its "period"), the latter which is chosen to satisfy the demands of the process it controls. Tasks controlling rapidly changing processes would tend to have shorter periods.
One scheduling system, termed "rate monotonic", for example, reviews each task to be run and the periods of those tasks and runs the ready task, as determined by each task's last running time, also having the shortest period. Other well known scheduling algorithms such as "earliest deadline first" and "least laxity first" employ different criteria to order the ready tasks for running. Provided the execution times and the periods of the tasks are well known, each of these scheduling systems can provide efficient use of the processor while ensuring that no periodic task misses its deadline. These scheduling methods give the programmer considerable flexibility in defining a control process as multiple periodic tasks.
Unfortunately, the above scheduling methods are not well suited to tasks that are not periodic, i.e., tasks that need to run only infrequently as triggered by some external occurrence that does not have a regular period. If such tasks are treated as periodic, so as to be included in the schedule, the period must be short to accommodate the need for rapid detection of the event triggering the task and prompt initiation of the task once it is triggered. This short period means that during many of those scheduled periods for the task, the task will not have been triggered and will not need to execute. Thus, processor time is wasted.
These event driven tasks that need only be executed when a certain event occurs are better accommodated with a hardware interrupt system. In one form of such a system, a signal on a physical interrupt line to the processor causes the processor circuitry to suspend its current task and jump to a new task identified by an "interrupt vector" stored in the processor's memory.
This hardware approach avoids the need to have the processor spend any time reading an input to determine whether the processor should start a new task. But, by the same token, hardware interrupt systems are inflexible and not readily modified through programming alone and thus limit the flexibility of the programmer to divide a control process into arbitrary tasks. Hardware interrupt systems are cumbersome when the relationship between tasks and triggering events is complex, i.e., where one event triggers multiple tasks or one task is triggered by multiple events.